unit clsImpressaoCheque;

interface

uses
  db, Dialogs, SysUtils, DBTables, WinTypes, Forms, Classes, StdCtrls;

type TImpressao = class
  protected
    FBanco: string;
    FNominal: string;
    FCidade: string;
    FData: string;
    FValor: string;

    Arquivo: TextFile;

    procedure DefinirBanco(sBanco: string);
    procedure DefinirNominal(sNominal: string);
    procedure DefinirCidade(sCidade: string);
    procedure DefinirData(sData: string);
    procedure DefinirValor(sValor: string);

    function StrZero(entrada: string; tamanho: integer): string;
    function StrToPChar(const Str: string): PChar;
    function WinExecAndWait32(FileName: string; WorkDir: string; Visibility: integer): integer;
    procedure Imprime(sLinha: string);
    procedure SetaPortaCom1;

  public
    property Banco: string read FBanco write DefinirBanco;
    property Nominal: string read FNominal write DefinirNominal;
    property Cidade: string read FCidade write DefinirCidade;
    property Data: string read FData write DefinirData;
    property Valor: string read FValor write DefinirValor;

    constructor Create;
    destructor Destroy; override;

    procedure Clear;
    function InicializaPorta(sPorta: string): Boolean;
    function FechaPorta(): Boolean;

    function EfetuaImpressaoCheque: Boolean;
  end;

implementation

{ TImpressao }

constructor TImpressao.Create;
begin
  inherited Create;
end;

destructor TImpressao.Destroy;
begin
  inherited;
end;

procedure TImpressao.DefinirBanco(sBanco: string);
begin
  Self.FBanco := chr(27) + 'b' + StrZero(sBanco, 3);
end;

procedure TImpressao.DefinirCidade(sCidade: string);
begin
  Self.FCidade := chr(27) + 'c' + sCidade + '$';
end;

procedure TImpressao.DefinirData(sData: string);
begin
  Self.FData := chr(27) + 'd' + copy(sData, 1, 2) + copy(sData, 4, 2) + copy(sData, 9, 2);
end;

procedure TImpressao.DefinirNominal(sNominal: string);
begin
  Self.FNominal := chr(27) + 'f' + sNominal + '$';
end;

procedure TImpressao.DefinirValor(sValor: string);
begin
  Self.FValor := chr(27) + 'v' + StrZero(FloatToStr(StrToFloat(sValor) * 100), 14);
end;

procedure TImpressao.Clear;
begin
  FBanco := '';
  FNominal := '';
  FCidade := '';
  FData := '30121899';
  FValor := '0';
end;


function TImpressao.FechaPorta: Boolean;
begin
  Result := False;
  try
    CloseFile(Arquivo);
    Result := True;
  except
  end;
end;

function TImpressao.InicializaPorta(sPorta: string): Boolean;
begin
  Result := False;
  try
    SetaPortaCom1;
    AssignFile(Arquivo, sPorta);
    Rewrite(Arquivo);
    Result := True;
  except
  end;
end;

function TImpressao.StrZero(entrada: string; tamanho: integer): string;
var
  retorno_str_zero: string;
  tamanho_str_entrada: integer;
  contador: integer;
begin
  tamanho_str_entrada := length(entrada);
  retorno_str_zero := '';
  for contador := 1 to tamanho - tamanho_str_entrada do begin
    retorno_str_zero := retorno_str_zero + '0';
  end;
  retorno_str_zero := retorno_str_zero + entrada;
  Result := retorno_str_zero;
end;

procedure TImpressao.Imprime(sLinha: string);
begin
  Writeln(Arquivo, sLinha);
end;

function TImpressao.EfetuaImpressaoCheque: Boolean;
begin
  Imprime(FBanco);
  Imprime(FNominal);
  Imprime(FCidade);
  Imprime(FData);
  Imprime(FValor);
end;

procedure TImpressao.SetaPortaCom1;
var
  Arq: TextFile;
  caminho: string;
begin
  caminho := ExtractFilePath(Application.ExeName);
  try
    AssignFile(Arq, caminho + 'Setar.bat');
    Rewrite(Arq);
    writeln(Arq, 'mode com1:9600, n, 8, 2, p');
    writeln(Arq, 'exit');
    CloseFile(Arq);
    try
      WinExecAndWait32(caminho + 'Setar.bat', caminho, SW_HIDE);
      DeleteFile(StrToPChar(caminho + 'Setar.bat'));
    finally
    end;
  except
  end;
end;

function TImpressao.StrToPChar(const Str: string): PChar;
type
  TRingIndex = 0..7;
var
  Ring: array[TRingIndex] of PChar;
  RingIndex: TRingIndex;
  Ptr: PChar;
begin
  Ptr := @Str[Length(Str)];
  Inc(Ptr);
  if Ptr^ = #0 then begin
    Result := @Str[1];
  end else begin
    Result := StrAlloc(Length(Str) + 1);
    RingIndex := (RingIndex + 1) mod (High(TRingIndex) + 1);
    StrPCopy(Result, Str);
    StrDispose(Ring[RingIndex]);
    Ring[RingIndex] := Result;
  end;
end;

function TImpressao.WinExecAndWait32(FileName, WorkDir: string;
  Visibility: integer): integer;
var
  zAppName: array[0..512] of char;
  zCurDir: array[0..255] of char;
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
begin
  StrPCopy(zAppName, FileName);
  StrPCopy(zCurDir, WorkDir);
  FillChar(StartupInfo, Sizeof(StartupInfo), #0);
  StartupInfo.cb := Sizeof(StartupInfo);
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
  StartupInfo.wShowWindow := Visibility;

  if not CreateProcess(nil, zAppName, nil, nil, False, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, zCurDir, StartupInfo, ProcessInfo) then
    Result := -1
  else
  begin
    WaitforSingleObject(ProcessInfo.hProcess, INFINITE);
    GetExitCodeProcess(ProcessInfo.hProcess, DWORD(Result));
  end;
end;

end.

